superstrict

import "Error.bmx"
import "SourceFile.bmx"

type errormanager

	'// -------------------------------------------------------------------------------------------------------------
	'// Write an error to the standard error stream.
	'// -------------------------------------------------------------------------------------------------------------
	function writeError(e:Error)
	
		local errorLine:string;
		
		if (not e.m_line) then
		
			e.m_line = new SourceLine;
			e.m_line.m_data = "";
			e.m_line.m_lineNumber = 0;
			e.m_line.m_source = null;
		
		end if
		
		if (not e.m_line.m_source) then
		
			e.m_line.m_source = new SourceFile;
			SourceFile(e.m_line.m_source).m_path = "unknown file";
		
		end if
		
		if (e.m_line.m_lineNumber < 1) ..
			errorLine = "unknown line"; ..
		else ..
			errorLine = e.m_line.m_lineNumber;
		
		local errorType:string = strutil.repeatstr("0", 4 - string(e.m_type).length) + e.m_type;
		local errorFile:string = SourceFile(e.m_line.m_source).m_path + "(" + errorLine + ") :";
		local errorData:string = e.m_data;
		local errorMsg:string;
		
		select (e.m_type)
		
			case Error.CUSTOM
				errorMsg = errorData;
			case Error.UNTERMINATED_COMMENT
				errorMsg = "Unterminated comment";
			case Error.UNTERMINATED_BRACKET
				errorMsg = "Unterminated '" + errorData + "' token";
			case Error.INVALID_TOKEN
				errorMsg = "Invalid token '" + errorData + "'";
			case Error.OPENING_BRACKET_MISSING
				errorMsg = "Expected '" + chr(errorData[0]) + "' before '" + chr(errorData[1]) + "' token";
			case Error.UNKNOWN_ESCAPE_SEQUENCE
				errorMsg = "Unknown escape sequence '" + errorData + "'";
			case Error.EXPECTED
				errorMsg = "Expected " + errorData + "";
			case Error.EXPECTED_A_BEFORE_B
				local data:string[] = errorData.split("#");
				errorMsg = "Expected '" + data[0] + "' before '" + data[1] + "' token";
			case Error.A_NOT_DECLARED_IN_SCOPE
				errorMsg = "'" + errorData + "' was not declared in this scope";
		
		end select
		
		writestderr(errorFile + " error " + errorType + ": " + errorMsg + ".~n");
	
	end function
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Make sure you never create an instance of this object, since it's acting as a namespace.
	'// -------------------------------------------------------------------------------------------------------------
	method new()
	
		local id:string = TTypeId.forObject(self).name()
		runtimeError("Illegal to create an instance of a namespace class '" + id + "'.")
	
	end method

end type

